package com.mano233.server.service.serviceImpl;

import com.github.pagehelper.PageHelper;
import com.mano233.server.mapper.EventsMapper;
import com.mano233.server.mapper.FileMapper;
import com.mano233.server.mapper.FormMapperCustom;
import com.mano233.server.mapper.UserMapperCustom;
import com.mano233.server.po.File;
import com.mano233.server.po.Form;
import com.mano233.server.po.FormUserEditor;
import com.mano233.server.po.User;
import com.mano233.server.service.FormService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public class FormServiceImpl implements FormService {
    private final FormMapperCustom formMapperCustom;
    private final UserMapperCustom userMapperCustom;
    private final UserServiceImpl userProfileService;
    private final EventsMapper eventsMapper;
    private FastDfsServiceImpl fastDfsServiceImpl;
    private FileMapper fileMapper;
    private static Logger logger = LoggerFactory.getLogger(FormServiceImpl.class);

    public FormServiceImpl(FormMapperCustom formMapperCustom, UserMapperCustom userMapperCustom, UserServiceImpl userProfileService, EventsMapper eventsMapper, FastDfsServiceImpl fastDfsServiceImpl, FileMapper fileMapper) {
        this.formMapperCustom = formMapperCustom;
        this.userMapperCustom = userMapperCustom;
        this.userProfileService = userProfileService;
        this.eventsMapper = eventsMapper;
        this.fastDfsServiceImpl = fastDfsServiceImpl;
        this.fileMapper = fileMapper;
    }

    /**
     * 查询用户对这个事件填写过表单(包括是小组成员)
     * 如果填写过则返回正在填写的表单id
     *
     * @param eventId 事件id
     * @param userId  用户id
     * @return 表单id，查询不到则返回-1
     */
    @Override
    public int hasForm(int eventId, int userId) {
        List<FormUserEditor> formList = userProfileService.getUserFormEditorList(userId);
        if (formList == null) {
            return -1;
        }
        for (FormUserEditor editor : formList) {
            int formEventId = editor.getEventId();
            if (eventId == formEventId) {
                return editor.getFormId();
            }
        }
        return -1;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public void accessForm(int formId, int adminId) {
        formMapperCustom.updateFormState(formId, 3);
    }

    /**
     * 新建一个新表单
     *
     * @param eventId 事件
     * @param userId  用户id
     * @return 返回新建表单的id
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public int createForm(int eventId, int userId) {
        return formMapperCustom.createNewForm(eventId, 5, userId, new Date());
    }

    /**
     * 查询一个事件下的所有表单
     *
     * @param eventId 事件id
     * @return List<FormUserEditor>
     */
    @Override
    public List<FormUserEditor> getFormList(int eventId, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return formMapperCustom.getFormList(eventId);
    }

    @Override
    public List<Form> getAuditForm(int eventId) {
        return formMapperCustom.getEventFormByState(eventId, 2);
    }

    @Override
    public List<Form> getAccessForm(int eventId) {
        return formMapperCustom.getEventFormByState(eventId, 3);
    }

    /**
     * 根据表单id删除表单
     */
    @Override
    @CacheEvict(value = "form", key = "#formId")
    public void deleteFormById(int uid, int formId) {
        formMapperCustom.deleteForm(formId);
    }

    /**
     * 更新表单
     *
     * @param updateForm     要更新的表单内容
     * @param insertUserList 要查插入的用户
     * @param deleteUserList 要删除的用户
     * @return 更新后的表单内容
     */
    @Override
    @CachePut(value = "form", key = "#updateForm.getFormId()")
    @Transactional(timeout = 2, rollbackFor = Exception.class)
    public FormUserEditor updateForm(FormUserEditor updateForm, List<User> insertUserList, List<User> deleteUserList) {
        String updateDescription = updateForm.getFormDescription();
        int updateFormId = updateForm.getFormId();
        int updateGroupId = updateForm.getFormGroupId();
        if (Objects.nonNull(updateDescription)) {
            formMapperCustom.updateFormDescription(updateDescription, updateFormId);
        }
        if (insertUserList != null && insertUserList.size() > 0) {
            formMapperCustom.insertFormGroupUser(updateGroupId, insertUserList);
        }
        if (deleteUserList != null && deleteUserList.size() > 0) {
            formMapperCustom.deleteFormGroupUser(updateGroupId, deleteUserList);
        }
        // 用户从新建状态改为带审核状态，如果管理员开启了邮件提醒则发送提醒，提示管理员审核表单
        if (updateForm.getFormStatus() == 0) {
            formMapperCustom.updateFormState(updateFormId, 2);
        }
        return formMapperCustom.getFormById(updateFormId);
    }


    /**
     * 根据表单id查询表单详情
     *
     * @param formId 表单id
     * @return FormUserEditor
     */
    @Override
    public FormUserEditor getFormById(int formId) {
        return formMapperCustom.getFormById(formId);
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public String uploadFile(MultipartFile file, int userId, int formId) throws Exception {
        String url = fastDfsServiceImpl.saveFile(file);
        File uploadFile = new File();
        uploadFile.setDisable(0);
        uploadFile.setFileCreateTime(new Date());
        uploadFile.setFileCreatorId(userId);
        uploadFile.setFileName(file.getOriginalFilename());
        uploadFile.setFilePath(url);
        uploadFile.setFileSize(file.getSize());
        uploadFile.setFileFormId(formId);
        fileMapper.insert(uploadFile);
        return url;
    }

    @Override
    public List<File> getFileList(int formId) {
        return formMapperCustom.getFileList(formId);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public void deleteFile(int formId, int fileId, String fileURL) throws Exception {
        URL url = new URL(fileURL);
        String[] result = url.getPath().split("/", 3);
        String groupName = result[1];
        String remoteFileName = result[2];
        formMapperCustom.deleteFile(formId, fileId);
        fastDfsServiceImpl.deleteFile(groupName, remoteFileName);
    }
}
